// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: Unified Transport Abstraction Layer Unified Transport Abstraction Layer
// ------------------------------------------------------------------

#include <transport/ChannelResource.h>

#include <asio.hpp>

#define MESSAGE_BUFFER_DEFAULT_SIZE 10500U  // max size of message buffer in bytes

namespace vbs {
namespace transport {

ChannelResource::ChannelResource() : buffer_size_(MESSAGE_BUFFER_DEFAULT_SIZE), alive_(true) {
    message_buffer_ = (unsigned char*)calloc(MESSAGE_BUFFER_DEFAULT_SIZE, sizeof(unsigned char));
    if (!message_buffer_) {
        logError(RTPS_MSG_IN, "Construct channelresource calloc buffer failed.");
    }
}

ChannelResource::ChannelResource(ChannelResource&& channelResource) : thread_(std::move(channelResource.thread_)) {

    buffer_size_ = channelResource.buffer_size_;
    message_buffer_ = (unsigned char*)malloc(buffer_size_);
    if (message_buffer_ != nullptr) {
        (void)memcpy(message_buffer_, channelResource.message_buffer_, buffer_size_);
    }
    bool b = channelResource.alive_;
    alive_.store(b);
}

ChannelResource::ChannelResource(uint32_t rec_buffer_size) : buffer_size_(rec_buffer_size), alive_(true) {
    message_buffer_ = (unsigned char*)calloc(rec_buffer_size, sizeof(unsigned char));
    if (!message_buffer_) {
        logError(RTPS_MSG_IN, "Construct channelresource calloc buffer failed.");
    }
}

ChannelResource::~ChannelResource() {
    ChannelResource::clear();
    if (message_buffer_) {
        free(message_buffer_);
        message_buffer_ = nullptr;
        buffer_size_ = 0;
    }
}

void ChannelResource::clear() {
    alive_.store(false);
    if (thread_.joinable()) {
        if (thread_.get_id() != std::this_thread::get_id()) {
            // wait for it to finish
            thread_.join();
        } else {
            // killing my own thread
            thread_.detach();
        }
    }
}

}  // namespace transport
}  // namespace vbs
